package org.cypress.rtpack.service;

import lombok.extern.slf4j.Slf4j;
import org.cypress.rtpack.entity.RtpackConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Slf4j
@Component
public class MdbsSlv1Service {
    @Autowired
    private IRtpackConfigService rtpackConfigService;

    private static final Logger logger = LoggerFactory.getLogger(MdbsSlv1Service.class);
    public static int unreply_After_Err = 8;
    private static int PORT = 7777;
    private static final int SOCKET_TIMEOUT_MS = 60000; // 20秒超时

    public void startServer() {
        logger.info("MdbsSlv1Service staring...");
        try {
            RtpackConfig rtpackConfig_port = rtpackConfigService.getByKey("portCommMoni");
            if (rtpackConfig_port != null && rtpackConfig_port.getValue() != null) {
                PORT = Integer.parseInt(rtpackConfig_port.getValue());
            } else {
                logger.info("从数据库未读取到CommMoni上传端口，采用默认值7777。");
                PORT = 7777;
            }
        } catch (Exception e) {
            logger.info("从数据库读取ToHMI端口失败，采用默认值7777。错误原因: " + e.getMessage());
            PORT = 7777;
        }

        new Thread(() -> {
            try (ServerSocket serverSocket = new ServerSocket(PORT)) {
                logger.info("MDBS-SLV1 Server started on port " + PORT);

                while (true) {
                    Socket clientSocket = serverSocket.accept();
                    logger.info("Client connected: " + clientSocket.getInetAddress());
                    // 检查条件（例如：IP黑名单、连接数限制等）
                    if (unreply_After_Err > 9) {
                        clientSocket.close(); // 拒绝连接
                        continue; // 继续等待下一个连接
                    }

                    // 设置超时并处理客户端请求
                    clientSocket.setSoTimeout(SOCKET_TIMEOUT_MS);
                    new Thread(() -> {
                        handleClient(clientSocket);
                    }).start();
                }
            } catch (IOException e) {
                logger.info("Server error: " + e.getMessage());
            }
        }).start();
    }

    private void handleClient(Socket clientSocket) {
        try{
            clientSocket.setSoTimeout(SOCKET_TIMEOUT_MS);
        } catch (IOException e) {
            logger.info("Server error: " + e.getMessage());
        }
        try (InputStream in = clientSocket.getInputStream();
             OutputStream out = clientSocket.getOutputStream()) {
            byte[] buffer = new byte[20];
            boolean isRunning = true;
            while (isRunning && (unreply_After_Err < 10)) {
                try {
                    int bytesRead = in.read(buffer);
                    if (bytesRead == -1) {
                        break; // 客户端关闭连接
                    }
                    if (bytesRead == 12) {
                        int staA = buffer[8] * 256 + buffer[9];
                        int lenV = buffer[10] * 256 + buffer[11];
                        if((buffer[2]==0) && (buffer[3]==0) && (buffer[4]==0) && (buffer[5]==6) && (buffer[7]==2) && (lenV <= 1600)){
                            int yu = (lenV - 1) % 8;
                            int uniLen = (lenV - 1 - yu) / 8 + 1;
                            byte[] responseBytesA = new byte[uniLen + 9];
                            responseBytesA[0] = buffer[0];
                            responseBytesA[1] = buffer[1];
                            responseBytesA[2] = 0;
                            responseBytesA[3] = 0;
                            responseBytesA[4] = 0;
                            responseBytesA[5] = (byte)(uniLen + 3);
                            responseBytesA[6] = buffer[6];
                            responseBytesA[7] = buffer[7];
                            responseBytesA[8] = (byte)(uniLen);
                            for (int i = 0; i < uniLen; i++) {
                                byte quan = 1;
                                byte vCur = 0;
                                for (int j = 0; j < 9; j++) {
                                    int t1 = staA + 8 * i + j;
                                    if (t1 < 100){
                                        if(CommMoniService.rom1[t1]){
                                            vCur += quan;
                                        }
                                        quan *= (byte)2;
                                    }
                                }
                                responseBytesA[9 + i] = vCur;
                            }
                            out.write(responseBytesA);
                            out.flush();
                        }
                    }
                } catch (SocketTimeoutException e) {
                    logger.info("MdbsSlv1 client timeout, closing connection..");
                    isRunning = false;
                } catch (IOException e) {
                    logger.info("MdbsSlv1 client handling error: " + e.getMessage());
                    isRunning = false;
                }
            }
        } catch (IOException e) {
            logger.info("Stream error: " + e.getMessage());
        } finally {
            try {
                clientSocket.close();
                logger.info("Client disconnected.");
            } catch (IOException e) {
                logger.error("Failed to close socket: " + e.getMessage());
            }
        }
    }
}